package cn.guetzjb.sys.controller;

import cn.guetzjb.core.entity.R;
import cn.guetzjb.core.utils.IpUtils;
import cn.guetzjb.security.anotation.InnerAuth;
import cn.guetzjb.security.anotation.RequiresRoles;
import cn.guetzjb.security.utils.SecurityUtils;
import cn.guetzjb.sys.domain.*;
import cn.guetzjb.sys.model.LoginUser;
import cn.guetzjb.sys.service.SysDeptService;
import cn.guetzjb.sys.service.SysRolePermService;
import cn.guetzjb.sys.service.SysUserRoleService;
import cn.guetzjb.sys.service.SysUserService;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@RequestMapping("/user")
@RestController
@RequiredArgsConstructor
@Tag(name = "用户管理", description = "用户管理")
public class UserController {

    private final SysUserService sysUserService;
    private final SysUserRoleService userRoleService;
    private final SysRolePermService rolePermService;
    private final SysDeptService deptService;

    @Operation(summary = "获取用户信息(inner)")
    @GetMapping("/info/{username}")
    @InnerAuth
    public R<LoginUser> info(@PathVariable String username) {
        SysUser sysUser = sysUserService.getRoleListByUsername(username);
        if (sysUser == null) {
            return R.failed("用户不存在");
        }
        return R.ok(createLoginUser(username, sysUser));
    }

    private LoginUser createLoginUser(String username, SysUser sysUser) {
        LoginUser loginUser = new LoginUser();
        loginUser.setUsername(username);
        loginUser.setSysUser(sysUser);
        loginUser.setUserId(sysUser.getUserId());
        loginUser.setIpaddr(IpUtils.getIpAddr());
        Set<String> roleKeySet = new HashSet<>();
        for (SysRole role : sysUser.getRoles()) {
            roleKeySet.add(role.getRoleKey());
        }
        loginUser.setRoles(roleKeySet);

        //查询部门
        SysDept dept = deptService.getOne(Wrappers.<SysDept>lambdaQuery().eq(SysDept::getDeptId, sysUser.getDeptId()));
        sysUser.setDept(dept);

        //构造权限
        Set<String> permission = new HashSet<>();
        List<SysRolePerm> rolePerms = rolePermService.list(Wrappers.<SysRolePerm>lambdaQuery().in(SysRolePerm::getRoleId, sysUser.getRoleIds()));
        for (SysRolePerm rolePerm : rolePerms) {
            permission.add(rolePerm.getPermKey());
        }
        loginUser.setPermissions(permission);
        return loginUser;
    }

    @Operation(summary = "获取用户信息")
    @GetMapping("/info")
    public R info() {
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        sysUser.setPassword("");
        return R.ok(sysUser);
    }

    @Operation(summary = "删除用户(需要权限)")
    @PostMapping("/delete/{ids}")
    @RequiresRoles(value = {"admin"})
    @Transactional
    public R delete(@PathVariable List<Long> ids) {
        if (ids.contains(SecurityUtils.getUserId())) {
            return R.failed("不能删除自己");
        }
        sysUserService.removeBatchByIds(ids);
        //逻辑删除 不删角色对应关系
//        for (Long id : ids) {
//            userRoleService.remove(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, id));
//        }
        return R.ok();
    }

    @Operation(summary = "查询用户列表(all)")
    @GetMapping("/all")
    @RequiresRoles(value = {"admin"})
    public R all() {
        List<SysUser> list = sysUserService.getUserAll();
        for (SysUser sysUser : list) {
            sysUser.setPassword("");
        }
        return R.ok(list);
    }

    @Operation(summary = "查询用户(id)")
    @GetMapping("/{id}")
    public R getById(@PathVariable Long id) {
        SysUser sysUser = sysUserService.getUserById(id);
        sysUser.setPassword("");
        return R.ok(sysUser);
    }

    @Operation(summary = "注册(inner)")
    @InnerAuth
    @PostMapping("/register/{username}/{password}")
    @Transactional
    public R register(@PathVariable String username, @PathVariable String password) {
        if (sysUserService.hasUser(username)) {
            return R.failed("用户名已经存在");
        }
        SysUser sysUser = sysUserService.registerUser(username, password);
        return R.ok(sysUser, "注册成功");
    }

    @Operation(summary = "更新用户信息(self)")
    @PostMapping("/update")
    public R update(@RequestBody SysUser sysUser) {
        Long userId = SecurityUtils.getUserId();
        sysUser.setUserId(userId);
        boolean ok = sysUserService.updateById(sysUser);
        if (ok) {
            return R.ok();
        }
        return R.failed("更新异常");
    }

    @Operation(summary = "更新用户信息(admin)")
    @PostMapping("/admin/update")
    @RequiresRoles(value = {"admin"})
    public R adminUpdate(@RequestBody SysUser sysUser) {
        Long userId = sysUser.getUserId();
        if (userId == null) {
            return R.failed("userId为空");
        }
        boolean ok = sysUserService.updateById(sysUser);
        if (ok) {
            return R.ok();
        }
        return R.failed("更新异常");
    }

    @Operation(summary = "查询用户列表(page)")
    @GetMapping("/page")
    public R getUserPage(@RequestParam(required = false, defaultValue = "1") Integer current,
                         @RequestParam(required = false, defaultValue = "10") Integer pageSize,
                         @RequestParam(required = false) String params) {
        Page<SysUser> page = sysUserService.page(new Page<>(current, pageSize), Wrappers.<SysUser>lambdaQuery()
                .like(!StringUtils.isEmpty(params), SysUser::getUserName, params)
                .or()
                .like(!StringUtils.isEmpty(params), SysUser::getNickName, params)
                .or()
                .like(!StringUtils.isEmpty(params), SysUser::getSex, "男".equals(params) ? "1" : "0")
                .or()
                .like(!StringUtils.isEmpty(params), SysUser::getPhonenumber, params)
        );
        return R.ok(page);
    }

    @Operation(summary = "用户名(like)")
    @GetMapping("/like")
    public R getUserNameLike(@RequestParam(required = false, defaultValue = "") String userName) {
        if ("".equals(userName)) {
            return R.ok(sysUserService.list());
        }
        List<SysUser> list = sysUserService.list(Wrappers.<SysUser>lambdaQuery()
                .like(SysUser::getUserName, userName)
                .or()
                .like(SysUser::getUserId, userName)
                .or()
                .like(SysUser::getNickName, userName));
        return R.ok(list);
    }

    @Operation(summary = "修改密码(inner)")
    @PostMapping("/changePwd/{userName}/{password}")
    @InnerAuth
    public boolean changePwd(@PathVariable String userName, @PathVariable String password) {
        String encryptPassword = SecurityUtils.encryptPassword(password);
        return sysUserService.update(null, Wrappers.<SysUser>lambdaUpdate()
                .set(SysUser::getPassword, encryptPassword)
                .eq(SysUser::getUserName, userName));
    }

}
